package test01.demo07;

import test01.demo02.userOperation.tools.Const;
import test01.demo03.ConnectionTool;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ObjectOperation {
    //将对象插入到对应的表中（表名与类名相同，字段名与属性名相同）
    public static void insert(Object object) {
        Connection conn = null;
        PreparedStatement ps = null;

        //获取对象的Class类型
        Class objClass = object.getClass();

        //获取当前对象的类名，直接作为sql语句的表名
        String tableName = objClass.getSimpleName();
        //获取当前对象的类中所有属性的数组
        Field[] fields = objClass.getDeclaredFields();

        try {
            Class.forName(Const.DRIVER);
            conn = DriverManager.getConnection(Const.URL_TEST, Const.USERNAME, Const.PASSWORD);

            //用StringBuffer拼接sql语句
            StringBuffer sb = new StringBuffer("insert into " + tableName.toLowerCase() + " values(");

            //有多少个属性就有多少个问号
            for (int i = 1; i <= fields.length; i++) {
                sb.append(i==fields.length?"?)":"?,");
            }

            System.out.println(sb.toString());

            //对这个sql语句进行预处理
            ps = conn.prepareStatement(sb.toString());

            //遍历所有的属性，获取这个对象中每个属性的值，分别设置相应的问号
            for (int i = 0; i < fields.length; i++) {
                //获取数组中的第i个属性
                Field currentField = fields[i];
                //把所有属性都设置为 私有 允许访问
                currentField.setAccessible(true);
                //从对象中获取相应属性的值
                Object fieldValue = currentField.get(object);
                //对相应的问号进行赋值
                ps.setObject(i+1,fieldValue);
            }

            int result = ps.executeUpdate();
            System.out.println(result);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            ConnectionTool.closed(conn,ps);
        }

    }

    //查询某个表中的所有记录，表名与类名相同，字段名与属性名相同
    public static <T> List<Map<String,Object>> getList(Class<T> clazz){
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet resultSet = null;
        List<Map<String,Object>> list = new ArrayList<>();

        //表名
        String tableName = clazz.getSimpleName();
        //属性数组
        Field[] fields = clazz.getDeclaredFields();

        try {
            Class.forName(Const.DRIVER);
            conn = DriverManager.getConnection(Const.URL_TEST,
                    Const.USERNAME,
                    Const.PASSWORD);

            StringBuffer sb = new StringBuffer(
                    "select * from " + tableName.toLowerCase()
            );


            ps = conn.prepareStatement(sb.toString());
            resultSet = ps.executeQuery();
            ResultSetMetaData rsmd = resultSet.getMetaData();
            int columnCount = rsmd.getColumnCount();
            while(resultSet.next()){
                Map<String,Object> map = new HashMap<>();
                for (int i = 1; i <= columnCount; i++) {
                    map.put(rsmd.getColumnName(i),resultSet.getObject(i));
                }
                list.add(map);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            ConnectionTool.closed(conn,ps,resultSet);
        }
        return list;
    }

    public static <T> List<Map<String,Object>> query(String sql, Class<T> clazz, Object... params){

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet resultSet = null;
        List<Map<String,Object>> list = new ArrayList<>();



        try {
            Class.forName(Const.DRIVER);
            conn = DriverManager.getConnection(Const.URL_TEST,
                    Const.USERNAME,
                    Const.PASSWORD);

            StringBuffer sb = new StringBuffer(
                    sql
            );


            ps = conn.prepareStatement(sb.toString());
            resultSet = ps.executeQuery();
            ResultSetMetaData rsmd = resultSet.getMetaData();
            int columnCount = rsmd.getColumnCount();
            while(resultSet.next()){
                Map<String,Object> map = new HashMap<>();
                for (int i = 1; i <= columnCount; i++) {
                    map.put(rsmd.getColumnName(i),resultSet.getObject(i));
                }
                list.add(map);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            ConnectionTool.closed(conn,ps,resultSet);
        }
        return list;
    }


    public static void main(String[] args) {

        Teacher teacher = new Teacher(100,"tom");
        Customers customers = new Customers(100,"jerry",20,"hrb",100);

        Class clazz = customers.getClass();
        //System.out.println(getList(clazz));
        System.out.println(query("select * from customers", clazz, null));

    }
}